home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / SLAX 6.0.8 / slax-6.0.8.iso / slax / base / 006-devel.lzm / usr / include / isc / task.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-09-17  |  14.7 KB  |  617 lines

  1. /*
  2.  * Copyright (C) 2004, 2005  Internet Systems Consortium, Inc. ("ISC")
  3.  * Copyright (C) 1998-2001, 2003  Internet Software Consortium.
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software for any
  6.  * purpose with or without fee is hereby granted, provided that the above
  7.  * copyright notice and this permission notice appear in all copies.
  8.  *
  9.  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  10.  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  11.  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  12.  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  13.  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  14.  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  15.  * PERFORMANCE OF THIS SOFTWARE.
  16.  */
  17.  
  18. /* $Id: task.h,v 1.51.18.2 2005/04/29 00:17:03 marka Exp $ */
  19.  
  20. #ifndef ISC_TASK_H
  21. #define ISC_TASK_H 1
  22.  
  23. /*****
  24.  ***** Module Info
  25.  *****/
  26.  
  27. /*! \file
  28.  * \brief The task system provides a lightweight execution context, which is
  29.  * basically an event queue.  
  30.  
  31.  * When a task's event queue is non-empty, the
  32.  * task is runnable.  A small work crew of threads, typically one per CPU,
  33.  * execute runnable tasks by dispatching the events on the tasks' event
  34.  * queues.  Context switching between tasks is fast.
  35.  *
  36.  * \li MP:
  37.  *    The module ensures appropriate synchronization of data structures it
  38.  *    creates and manipulates.
  39.  *    The caller must ensure that isc_taskmgr_destroy() is called only
  40.  *    once for a given manager.
  41.  *
  42.  * \li Reliability:
  43.  *    No anticipated impact.
  44.  *
  45.  * \li Resources:
  46.  *    TBS
  47.  *
  48.  * \li Security:
  49.  *    No anticipated impact.
  50.  *
  51.  * \li Standards:
  52.  *    None.
  53.  *
  54.  * \section purge Purging and Unsending
  55.  *
  56.  * Events which have been queued for a task but not delivered may be removed
  57.  * from the task's event queue by purging or unsending.
  58.  *
  59.  * With both types, the caller specifies a matching pattern that selects
  60.  * events based upon their sender, type, and tag.
  61.  *
  62.  * Purging calls isc_event_free() on the matching events.
  63.  *
  64.  * Unsending returns a list of events that matched the pattern.
  65.  * The caller is then responsible for them.
  66.  *
  67.  * Consumers of events should purge, not unsend.
  68.  *
  69.  * Producers of events often want to remove events when the caller indicates
  70.  * it is no longer interested in the object, e.g. by cancelling a timer.
  71.  * Sometimes this can be done by purging, but for some event types, the
  72.  * calls to isc_event_free() cause deadlock because the event free routine
  73.  * wants to acquire a lock the caller is already holding.  Unsending instead
  74.  * of purging solves this problem.  As a general rule, producers should only
  75.  * unsend events which they have sent.
  76.  */
  77.  
  78.  
  79. /***
  80.  *** Imports.
  81.  ***/
  82.  
  83. #include <isc/eventclass.h>
  84. #include <isc/lang.h>
  85. #include <isc/stdtime.h>
  86. #include <isc/types.h>
  87.  
  88. #define ISC_TASKEVENT_FIRSTEVENT    (ISC_EVENTCLASS_TASK + 0)
  89. #define ISC_TASKEVENT_SHUTDOWN        (ISC_EVENTCLASS_TASK + 1)
  90. #define ISC_TASKEVENT_LASTEVENT        (ISC_EVENTCLASS_TASK + 65535)
  91.  
  92. /*****
  93.  ***** Tasks.
  94.  *****/
  95.  
  96. ISC_LANG_BEGINDECLS
  97.  
  98. isc_result_t
  99. isc_task_create(isc_taskmgr_t *manager, unsigned int quantum,
  100.         isc_task_t **taskp);
  101. /*%<
  102.  * Create a task.
  103.  *
  104.  * Notes:
  105.  *
  106.  *\li    If 'quantum' is non-zero, then only that many events can be dispatched
  107.  *    before the task must yield to other tasks waiting to execute.  If
  108.  *    quantum is zero, then the default quantum of the task manager will
  109.  *    be used.
  110.  *
  111.  *\li    The 'quantum' option may be removed from isc_task_create() in the
  112.  *    future.  If this happens, isc_task_getquantum() and
  113.  *    isc_task_setquantum() will be provided.
  114.  *
  115.  * Requires:
  116.  *
  117.  *\li    'manager' is a valid task manager.
  118.  *
  119.  *\li    taskp != NULL && *taskp == NULL
  120.  *
  121.  * Ensures:
  122.  *
  123.  *\li    On success, '*taskp' is bound to the new task.
  124.  *
  125.  * Returns:
  126.  *
  127.  *\li   #ISC_R_SUCCESS
  128.  *\li    #ISC_R_NOMEMORY
  129.  *\li    #ISC_R_UNEXPECTED
  130.  *\li    #ISC_R_SHUTTINGDOWN
  131.  */
  132.  
  133. void
  134. isc_task_attach(isc_task_t *source, isc_task_t **targetp);
  135. /*%<
  136.  * Attach *targetp to source.
  137.  *
  138.  * Requires:
  139.  *
  140.  *\li    'source' is a valid task.
  141.  *
  142.  *\li    'targetp' points to a NULL isc_task_t *.
  143.  *
  144.  * Ensures:
  145.  *
  146.  *\li    *targetp is attached to source.
  147.  */
  148.  
  149. void
  150. isc_task_detach(isc_task_t **taskp);
  151. /*%<
  152.  * Detach *taskp from its task.
  153.  *
  154.  * Requires:
  155.  *
  156.  *\li    '*taskp' is a valid task.
  157.  *
  158.  * Ensures:
  159.  *
  160.  *\li    *taskp is NULL.
  161.  *
  162.  *\li    If '*taskp' is the last reference to the task, the task is idle (has
  163.  *    an empty event queue), and has not been shutdown, the task will be
  164.  *    shutdown.
  165.  *
  166.  *\li    If '*taskp' is the last reference to the task and
  167.  *    the task has been shutdown,
  168.  *        all resources used by the task will be freed.
  169.  */
  170.  
  171. void
  172. isc_task_send(isc_task_t *task, isc_event_t **eventp);
  173. /*%<
  174.  * Send '*event' to 'task'.
  175.  *
  176.  * Requires:
  177.  *
  178.  *\li    'task' is a valid task.
  179.  *\li    eventp != NULL && *eventp != NULL.
  180.  *
  181.  * Ensures:
  182.  *
  183.  *\li    *eventp == NULL.
  184.  */
  185.  
  186. void
  187. isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp);
  188. /*%<
  189.  * Send '*event' to '*taskp' and then detach '*taskp' from its
  190.  * task.
  191.  *
  192.  * Requires:
  193.  *
  194.  *\li    '*taskp' is a valid task.
  195.  *\li    eventp != NULL && *eventp != NULL.
  196.  *
  197.  * Ensures:
  198.  *
  199.  *\li    *eventp == NULL.
  200.  *
  201.  *\li    *taskp == NULL.
  202.  *
  203.  *\li    If '*taskp' is the last reference to the task, the task is
  204.  *    idle (has an empty event queue), and has not been shutdown,
  205.  *    the task will be shutdown.
  206.  *
  207.  *\li    If '*taskp' is the last reference to the task and
  208.  *    the task has been shutdown,
  209.  *        all resources used by the task will be freed.
  210.  */
  211.  
  212.  
  213. unsigned int
  214. isc_task_purgerange(isc_task_t *task, void *sender, isc_eventtype_t first,
  215.             isc_eventtype_t last, void *tag);
  216. /*%<
  217.  * Purge events from a task's event queue.
  218.  *
  219.  * Requires:
  220.  *
  221.  *\li    'task' is a valid task.
  222.  *
  223.  *\li    last >= first
  224.  *
  225.  * Ensures:
  226.  *
  227.  *\li    Events in the event queue of 'task' whose sender is 'sender', whose
  228.  *    type is >= first and <= last, and whose tag is 'tag' will be purged,
  229.  *    unless they are marked as unpurgable.
  230.  *
  231.  *\li    A sender of NULL will match any sender.  A NULL tag matches any
  232.  *    tag.
  233.  *
  234.  * Returns:
  235.  *
  236.  *\li    The number of events purged.
  237.  */
  238.  
  239. unsigned int
  240. isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type,
  241.            void *tag);
  242. /*%<
  243.  * Purge events from a task's event queue.
  244.  *
  245.  * Notes:
  246.  *
  247.  *\li    This function is equivalent to
  248.  *
  249.  *\code
  250.  *        isc_task_purgerange(task, sender, type, type, tag);
  251.  *\endcode
  252.  *
  253.  * Requires:
  254.  *
  255.  *\li    'task' is a valid task.
  256.  *
  257.  * Ensures:
  258.  *
  259.  *\li    Events in the event queue of 'task' whose sender is 'sender', whose
  260.  *    type is 'type', and whose tag is 'tag' will be purged, unless they
  261.  *    are marked as unpurgable.
  262.  *
  263.  *\li    A sender of NULL will match any sender.  A NULL tag matches any
  264.  *    tag.
  265.  *
  266.  * Returns:
  267.  *
  268.  *\li    The number of events purged.
  269.  */
  270.  
  271. isc_boolean_t
  272. isc_task_purgeevent(isc_task_t *task, isc_event_t *event);
  273. /*%<
  274.  * Purge 'event' from a task's event queue.
  275.  *
  276.  * XXXRTH:  WARNING:  This method may be removed before beta.
  277.  *
  278.  * Notes:
  279.  *
  280.  *\li    If 'event' is on the task's event queue, it will be purged,
  281.  *     unless it is marked as unpurgeable.  'event' does not have to be
  282.  *    on the task's event queue; in fact, it can even be an invalid
  283.  *    pointer.  Purging only occurs if the event is actually on the task's
  284.  *    event queue.
  285.  *
  286.  * \li    Purging never changes the state of the task.
  287.  *
  288.  * Requires:
  289.  *
  290.  *\li    'task' is a valid task.
  291.  *
  292.  * Ensures:
  293.  *
  294.  *\li    'event' is not in the event queue for 'task'.
  295.  *
  296.  * Returns:
  297.  *
  298.  *\li    #ISC_TRUE            The event was purged.
  299.  *\li    #ISC_FALSE            The event was not in the event queue,
  300.  *                    or was marked unpurgeable.
  301.  */
  302.  
  303. unsigned int
  304. isc_task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first,
  305.              isc_eventtype_t last, void *tag, isc_eventlist_t *events);
  306. /*%<
  307.  * Remove events from a task's event queue.
  308.  *
  309.  * Requires:
  310.  *
  311.  *\li    'task' is a valid task.
  312.  *
  313.  *\li    last >= first.
  314.  *
  315.  *\li    *events is a valid list.
  316.  *
  317.  * Ensures:
  318.  *
  319.  *\li    Events in the event queue of 'task' whose sender is 'sender', whose
  320.  *    type is >= first and <= last, and whose tag is 'tag' will be dequeued
  321.  *    and appended to *events.
  322.  *
  323.  *\li    A sender of NULL will match any sender.  A NULL tag matches any
  324.  *    tag.
  325.  *
  326.  * Returns:
  327.  *
  328.  *\li    The number of events unsent.
  329.  */
  330.  
  331. unsigned int
  332. isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,
  333.         void *tag, isc_eventlist_t *events);
  334. /*%<
  335.  * Remove events from a task's event queue.
  336.  *
  337.  * Notes:
  338.  *
  339.  *\li    This function is equivalent to
  340.  *
  341.  *\code
  342.  *        isc_task_unsendrange(task, sender, type, type, tag, events);
  343.  *\endcode
  344.  *
  345.  * Requires:
  346.  *
  347.  *\li    'task' is a valid task.
  348.  *
  349.  *\li    *events is a valid list.
  350.  *
  351.  * Ensures:
  352.  *
  353.  *\li    Events in the event queue of 'task' whose sender is 'sender', whose
  354.  *    type is 'type', and whose tag is 'tag' will be dequeued and appended
  355.  *    to *events.
  356.  *
  357.  * Returns:
  358.  *
  359.  *\li    The number of events unsent.
  360.  */
  361.  
  362. isc_result_t
  363. isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action,
  364.             const void *arg);
  365. /*%<
  366.  * Send a shutdown event with action 'action' and argument 'arg' when
  367.  * 'task' is shutdown.
  368.  *
  369.  * Notes:
  370.  *
  371.  *\li    Shutdown events are posted in LIFO order.
  372.  *
  373.  * Requires:
  374.  *
  375.  *\li    'task' is a valid task.
  376.  *
  377.  *\li    'action' is a valid task action.
  378.  *
  379.  * Ensures:
  380.  *
  381.  *\li    When the task is shutdown, shutdown events requested with
  382.  *    isc_task_onshutdown() will be appended to the task's event queue.
  383.  *
  384.  
  385.  * Returns:
  386.  *
  387.  *\li    #ISC_R_SUCCESS
  388.  *\li    #ISC_R_NOMEMORY
  389.  *\li    #ISC_R_TASKSHUTTINGDOWN            Task is shutting down.
  390.  */
  391.  
  392. void
  393. isc_task_shutdown(isc_task_t *task);
  394. /*%<
  395.  * Shutdown 'task'.
  396.  *
  397.  * Notes:
  398.  *
  399.  *\li    Shutting down a task causes any shutdown events requested with
  400.  *    isc_task_onshutdown() to be posted (in LIFO order).  The task
  401.  *    moves into a "shutting down" mode which prevents further calls
  402.  *    to isc_task_onshutdown().
  403.  *
  404.  *\li    Trying to shutdown a task that has already been shutdown has no
  405.  *    effect.
  406.  *
  407.  * Requires:
  408.  *
  409.  *\li    'task' is a valid task.
  410.  *
  411.  * Ensures:
  412.  *
  413.  *\li    Any shutdown events requested with isc_task_onshutdown() have been
  414.  *    posted (in LIFO order).
  415.  */
  416.  
  417. void
  418. isc_task_destroy(isc_task_t **taskp);
  419. /*%<
  420.  * Destroy '*taskp'.
  421.  *
  422.  * Notes:
  423.  *
  424.  *\li    This call is equivalent to:
  425.  *
  426.  *\code
  427.  *        isc_task_shutdown(*taskp);
  428.  *        isc_task_detach(taskp);
  429.  *\endcode
  430.  *
  431.  * Requires:
  432.  *
  433.  *    '*taskp' is a valid task.
  434.  *
  435.  * Ensures:
  436.  *
  437.  *\li    Any shutdown events requested with isc_task_onshutdown() have been
  438.  *    posted (in LIFO order).
  439.  *
  440.  *\li    *taskp == NULL
  441.  *
  442.  *\li    If '*taskp' is the last reference to the task,
  443.  *        all resources used by the task will be freed.
  444.  */
  445.  
  446. void
  447. isc_task_setname(isc_task_t *task, const char *name, void *tag);
  448. /*%<
  449.  * Name 'task'.
  450.  *
  451.  * Notes:
  452.  *
  453.  *\li    Only the first 15 characters of 'name' will be copied.
  454.  *
  455.  *\li    Naming a task is currently only useful for debugging purposes.
  456.  *
  457.  * Requires:
  458.  *
  459.  *\li    'task' is a valid task.
  460.  */
  461.  
  462. const char *
  463. isc_task_getname(isc_task_t *task);
  464. /*%<
  465.  * Get the name of 'task', as previously set using isc_task_setname().
  466.  *
  467.  * Notes:
  468.  *\li    This function is for debugging purposes only.
  469.  *
  470.  * Requires:
  471.  *\li    'task' is a valid task.
  472.  *
  473.  * Returns:
  474.  *\li    A non-NULL pointer to a null-terminated string.
  475.  *     If the task has not been named, the string is
  476.  *     empty.
  477.  *
  478.  */
  479.  
  480. void *
  481. isc_task_gettag(isc_task_t *task);
  482. /*%<
  483.  * Get the tag value for  'task', as previously set using isc_task_settag().
  484.  *
  485.  * Notes:
  486.  *\li    This function is for debugging purposes only.
  487.  *
  488.  * Requires:
  489.  *\li    'task' is a valid task.
  490.  */
  491.  
  492. isc_result_t
  493. isc_task_beginexclusive(isc_task_t *task);
  494. /*%<
  495.  * Request exclusive access for 'task', which must be the calling
  496.  * task.  Waits for any other concurrently executing tasks to finish their
  497.  * current event, and prevents any new events from executing in any of the
  498.  * tasks sharing a task manager with 'task'.
  499.  *
  500.  * The exclusive access must be relinquished by calling 
  501.  * isc_task_endexclusive() before returning from the current event handler.
  502.  *
  503.  * Requires:
  504.  *\li    'task' is the calling task.
  505.  *
  506.  * Returns:
  507.  *\li    #ISC_R_SUCCESS        The current task now has exclusive access.
  508.  *\li    #ISC_R_LOCKBUSY        Another task has already requested exclusive
  509.  *                access.
  510.  */
  511.  
  512. void
  513. isc_task_endexclusive(isc_task_t *task);
  514. /*%<
  515.  * Relinquish the exclusive access obtained by isc_task_beginexclusive(), 
  516.  * allowing other tasks to execute.
  517.  *
  518.  * Requires:
  519.  *\li    'task' is the calling task, and has obtained
  520.  *        exclusive access by calling isc_task_spl().
  521.  */
  522.  
  523. void
  524. isc_task_getcurrenttime(isc_task_t *task, isc_stdtime_t *t);
  525. /*%<
  526.  * Provide the most recent timestamp on the task.  The timestamp is considered
  527.  * as the "current time" in the second-order granularity.
  528.  *
  529.  * Requires:
  530.  *\li    'task' is a valid task.
  531.  *\li    't' is a valid non NULL pointer.
  532.  *
  533.  * Ensures:
  534.  *\li    '*t' has the "current time".
  535.  */
  536.  
  537. /*****
  538.  ***** Task Manager.
  539.  *****/
  540.  
  541. isc_result_t
  542. isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
  543.            unsigned int default_quantum, isc_taskmgr_t **managerp);
  544. /*%<
  545.  * Create a new task manager.
  546.  *
  547.  * Notes:
  548.  *
  549.  *\li    'workers' in the number of worker threads to create.  In general,
  550.  *    the value should be close to the number of processors in the system.
  551.  *    The 'workers' value is advisory only.  An attempt will be made to
  552.  *    create 'workers' threads, but if at least one thread creation
  553.  *    succeeds, isc_taskmgr_create() may return ISC_R_SUCCESS.
  554.  *
  555.  *\li    If 'default_quantum' is non-zero, then it will be used as the default
  556.  *    quantum value when tasks are created.  If zero, then an implementation
  557.  *    defined default quantum will be used.
  558.  *
  559.  * Requires:
  560.  *
  561.  *\li      'mctx' is a valid memory context.
  562.  *
  563.  *\li    workers > 0
  564.  *
  565.  *\li    managerp != NULL && *managerp == NULL
  566.  *
  567.  * Ensures:
  568.  *
  569.  *\li    On success, '*managerp' will be attached to the newly created task
  570.  *    manager.
  571.  *
  572.  * Returns:
  573.  *
  574.  *\li    #ISC_R_SUCCESS
  575.  *\li    #ISC_R_NOMEMORY
  576.  *\li    #ISC_R_NOTHREADS            No threads could be created.
  577.  *\li    #ISC_R_UNEXPECTED        An unexpected error occurred.
  578.  */
  579.  
  580. void
  581. isc_taskmgr_destroy(isc_taskmgr_t **managerp);
  582. /*%<
  583.  * Destroy '*managerp'.
  584.  *
  585.  * Notes:
  586.  *
  587.  *\li    Calling isc_taskmgr_destroy() will shutdown all tasks managed by
  588.  *    *managerp that haven't already been shutdown.  The call will block
  589.  *    until all tasks have entered the done state.
  590.  *
  591.  *\li    isc_taskmgr_destroy() must not be called by a task event action,
  592.  *    because it would block forever waiting for the event action to
  593.  *    complete.  An event action that wants to cause task manager shutdown
  594.  *    should request some non-event action thread of execution to do the
  595.  *    shutdown, e.g. by signalling a condition variable or using
  596.  *    isc_app_shutdown().
  597.  *
  598.  *\li    Task manager references are not reference counted, so the caller
  599.  *    must ensure that no attempt will be made to use the manager after
  600.  *    isc_taskmgr_destroy() returns.
  601.  *
  602.  * Requires:
  603.  *
  604.  *\li    '*managerp' is a valid task manager.
  605.  *
  606.  *\li    isc_taskmgr_destroy() has not be called previously on '*managerp'.
  607.  *
  608.  * Ensures:
  609.  *
  610.  *\li    All resources used by the task manager, and any tasks it managed,
  611.  *    have been freed.
  612.  */
  613.  
  614. ISC_LANG_ENDDECLS
  615.  
  616. #endif /* ISC_TASK_H */
  617.